package UIFree.controls {
	import UIFree.*;
	
	import flash.events.Event;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	public class uif_scrollArea extends uif_ecomponent {
		public static const CREATE_ELEM: String = 'CREATE_ELEM';
		public static const SCROLLING: String = 'SCROLLING';
		
		private var _mask: uif_draw;
		private var _area: uif_ecomponent;
		private var _list: Array;
		private var _scrollTansition: Function;
		private var _scrollDuration: uint;
		
		
		public function uif_scrollArea(parent: uif_component, 
					ax: int=0, ay: int=0, 
					awidth: int=0, aheight: int=0, styleClass: String='') {
			_mask = new uif_draw();
			addChild(_mask);
			super(parent, ax, ay, awidth, aheight, styleClass);
			_area = new uif_ecomponent(this, 0, 0, awidth, aheight, 'scrollArea');
			_area.mask = _mask;
			
			setScrollTransition(uif_transition.easeInOut(uif_transition.Back, 2));
		}
		
		public function setScrollTransition(a_func: Function, a_duration: uint=300): void {
			_scrollTansition = a_func;
			_scrollDuration = a_duration;
		}
		
		public function get area(): uif_ecomponent {
			return _area;
		}
		
		public function get list(): Array {
			return _list; 
		}
		
		public function get empty(): Boolean {
			return !_list || (_list.length == 0);
		}
		
		protected function checkScroll(x_to: Number, y_to: Number): Boolean {
			var aRect: Rectangle = _area.getOuter();
			aRect.offset(x_to, y_to);
			var mRect: Rectangle = maskRect;
			return aRect.containsRect(mRect);
		}
		
		public function get maskRect(): Rectangle {
			return new Rectangle(0, 0, _mask.width, _mask.height);
		}
		
		public function scrollTo(x_to: Number, y_to: Number): void {
			function doScrolling(): void {
				dispatchEvent(new Event(SCROLLING));
			}
			
			var cfx: FX;
			if ((cfx = _area.getFX('x')) != null) cfx.cancel();
			if ((cfx = _area.getFX('y')) != null) cfx.cancel();
			
			if (checkScroll(x_to, y_to)) {
				var st: Point = new Point(_area.x + x_to, _area.y + y_to);
				if (x_to != 0) _area.fx('x', _area.x, st.x, _scrollTansition, 50, _scrollDuration).start(doScrolling, function(e: FXEvent): void {
									_area.x = st.x;
									doScrolling();
								});
				if (y_to != 0) _area.fx('y', _area.y, st.y, _scrollTansition, 50, _scrollDuration).start(doScrolling, function(e: FXEvent): void {
									_area.y = st.y;
									doScrolling();
								});
			}
		}
		
		public function scrollToItem(item: uif_component): void {
			var bi: Number = item.y + item.height + _area.y; 
			var ti: Number = item.y + _area.y;
			var inner: Rectangle = this.getInner();
			if (bi > inner.bottom) scrollTo(0, inner.bottom - bi); 
			if (ti < 0) scrollTo(0, -ti); 
		}
		
		// elemCreate(area: uif_component, item:*, index: int): uif_component
		public function attachList(list: Array, elemCreate:*): uif_scrollArea {
			var index: int = 0;
			if (_list) {
				index = _list.length;
				if (list) _list = _list.concat(list);
			} else _list = list;
			var size: Point = new Point(0, 0);
			if (list)
				for (var i: int=0; i<list.length; i++) {
					var elem: uif_component = elemCreate(_area, list[i], index);
					if (elem) {
						elem._data = list[i];
						this.dispatchEvent(new ObjectEvent(CREATE_ELEM, elem));
						if (elem) {
							if (size.x < elem.x + elem.width) size.x = elem.x + elem.width;
							if (size.y < elem.y + elem.height) size.y = elem.y + elem.height;
						}
						index++;
					}
				}
			_area.resize((size.x > width)?size.x:width,
						(size.y > height)?size.y:height);
			return this;
		}
		
		public function removeItem(item: uif_ecomponent): void {
			var index: int = _area.getChildIndex(item);
			if (index > -1) {
				_list.splice(index, 1);
				var h: int = item.height;
				item.dispose();
				for (var i: int=index; i<_area.numChildren; i++) {
					_area.getChildAt(i).y -= h;
				}
				_area.resize(_area.width, _area.height-h);
				if (_area.y + _area.height < height) scrollTo(0, height - (_area.y + _area.height));
			}
		}
		
		public function removeItems(): void {
			if (_list) _list.splice(0, _list.length);
			_area.removeChilds();
			_area.resize(_area.width, 0);
			_area.x = 0;
			_area.y = 0;
		}
		
		override protected function updateBounds(): uif_component {
			_mask.graphics.clear();
			var inner: Rectangle = getInner();
			_mask.draw_rect(inner.x, inner.y, inner.width, inner.height, {fill_color: 0, fill_alpha: 1, rounds: style.rounds});
			return super.updateBounds();
		}		
	}
}